package histogram;

import draw.ArrayFromImage;
import draw.ExploringMedics;
import filters.CleanRegionNeiro;
import java.awt.image.BufferedImage;
import java.awt.image.WritableRaster;
import java.util.ArrayList;

public class NeiroMarkImage {

    HistogramDescr histogram;
    BufferedImage originalImage;
    BufferedImage paintedImage;
    ArrayList<Integer> neiroLabels;
    int edgeMatr[][];
    int mitahMatr[][];
    int lipidMatr[][];
    int backMatr[][];
    int resultMatrix[][];
    int[][] imArray;
    int xMax = 0;
    int yMax = 0;

    public NeiroMarkImage(HistogramDescr histogram, BufferedImage originalImage) {
        this.histogram = histogram;
        this.originalImage = originalImage;
        ArrayFromImage arFromIm = new ArrayFromImage(originalImage);
        imArray = arFromIm.getImageDescription();

        xMax = histogram.width - histogram.width % histogram.offset;
        yMax = histogram.height - histogram.height % histogram.offset;

        NeiroWork workNeiro = new NeiroWork();
        workNeiro.loadNetwork(ExploringMedics.currentMitachProperties.getEgFile());
        neiroLabels = workNeiro.workNetwork(histogram.valueList);

        paintedImage = new BufferedImage(histogram.width, histogram.height,
                BufferedImage.TYPE_4BYTE_ABGR);

        readResults();
        prepareResultMatrix();
        
        CleanRegionNeiro cleanNeiro = new CleanRegionNeiro(resultMatrix);
        cleanNeiro.doClean();
        resultMatrix = cleanNeiro.getCleanResult();
        
        paintImage(originalImage);
    }

    public BufferedImage getPaintedImage() {
        return paintedImage;
    }
    
    void prepareResultMatrix() {
        for (int i = 0; i < xMax; i++) {
            for (int j = 0; j < yMax; j++) {

                int max = edgeMatr[i][j];
                int index = HistogramDescr.EDGE;
                if (mitahMatr[i][j] > max) {
                    max = mitahMatr[i][j];
                    index = HistogramDescr.MITAH;
                }
                if (lipidMatr[i][j] > max) {
                    max = lipidMatr[i][j];
                    index = HistogramDescr.LIPID;
                }
                if (backMatr[i][j] > max) {
                    max = backMatr[i][j];
                    index = HistogramDescr.BACK;
                }

                switch (index) {
                    case HistogramDescr.EDGE:
                        resultMatrix[i][j] = HistogramDescr.BACK;
                        break;
                    case HistogramDescr.MITAH:
                        resultMatrix[i][j] = HistogramDescr.LIPID;
                        break;
                    case HistogramDescr.LIPID:
                        resultMatrix[i][j] = HistogramDescr.MITAH;
                        break;
                    case HistogramDescr.BACK:
                        resultMatrix[i][j] = HistogramDescr.BACK;
                        break;
                }
            }
        }

    }

    private void paintImage(BufferedImage image) {
        int mitColor[] = {100, 200, 255, 0};
        int lipidColor[] = {22, 200, 0, 0};

        for (int i = 0; i < xMax; i++) {
            for (int j = 0; j < yMax; j++) {

                WritableRaster raster = paintedImage.getRaster();

                int curColor[] = new int[4];
                curColor[0] = imArray[i][j];
                curColor[1] = imArray[i][j];
                curColor[2] = imArray[i][j];
                curColor[3] = ExploringMedics.WHITE;

                switch (resultMatrix[i][j]) {
                    case HistogramDescr.EDGE:
//                        for (int p = 0; p < 4; p++) {
//                            curColor[p] = (curColor[p] + edgeColor[p]) / 2;
//                        }
                        break;
                    case HistogramDescr.MITAH:
                        for (int p = 0; p < 4; p++) {
                            curColor[p] = (curColor[p] + mitColor[p]) / 2;
                        }
                        break;
                    case HistogramDescr.LIPID:
                        for (int p = 0; p < 4; p++) {
                            curColor[p] = (curColor[p] + lipidColor[p]) / 2;
                        }
                        break;
                    case HistogramDescr.BACK:
//                        for (int p = 0; p < 4; p++) {
//                            curColor[p] = (curColor[p] + edgeColor[p]) / 2;
//                        }
                        break;
                }
                raster.setPixel(i, j, curColor);
            }
        }
        System.out.println("painted");
    }

    public int[][] getResultMatrix() {
        return resultMatrix;
    }

    void readResults() {

        edgeMatr = new int[xMax][yMax];
        lipidMatr = new int[xMax][yMax];
        mitahMatr = new int[xMax][yMax];
        backMatr = new int[xMax][yMax];

        resultMatrix = new int[xMax][yMax];

        init(xMax, yMax, edgeMatr);
        init(xMax, yMax, lipidMatr);
        init(xMax, yMax, mitahMatr);
        init(xMax, yMax, backMatr);
        init(xMax, yMax, resultMatrix);

        System.out.println("neiroRes size " + neiroLabels.size());

        for (int i = 0; i < neiroLabels.size(); i++) {
            int x = histogram.xList.get(i);
            int y = histogram.yList.get(i);

            int actualLabel = neiroLabels.get(i);

            switch (actualLabel) {
                case 0:
                    mark(x, y, edgeMatr);
                    break;
                case 1:
                    mark(x, y, mitahMatr);
                    break;
                case 2:
                    mark(x, y, lipidMatr);
                    break;
                case 3:
                    mark(x, y, backMatr);
                    break;
            }
        }
        System.out.println("readed");

    }

    private void init(int xMax, int yMax, int mas[][]) {
        for (int i = 0; i < xMax; i++) {
            for (int j = 0; j < yMax; j++) {
                mas[i][j] = 0;
            }
        }
    }

    private void mark(int x, int y, int mas[][]) {
        for (int i = x; i < x + histogram.window; i++) {
            for (int j = y; j < y + histogram.window; j++) {
                mas[i][j]++;
            }
        }
    }
}
